package com.edt.ichannel.api.service.impl;

import cc.edt.iceutils2.random.IceRandomUtils;
import cc.edt.iceutils3.date.IceDateOperationUtils;
import com.edt.ichannel.api.common.constant.CommonConstant;
import com.edt.ichannel.api.entiy.local.*;
import com.edt.ichannel.api.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Slf4j
@Service
public class ComputeServiceImpl implements ComputeService {
    @Resource
    private CommissionRootRuleService commissionRootRuleService;

    @Resource
    private OrderCreditMonthService orderCreditMonthService;

    @Resource
    private OrderCreditCKService orderCreditCKService;
    @Resource
    private OrderCreditKdService orderCreditKdService;
    @Resource
    private OrderCreditService orderCreditService;
    @Resource
    private EdtApiService edtApiService;

    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void computCommissionCK(OrderCreditCK orderCreditCK) {
        if(orderCreditCK != null && orderCreditCK.getFirstMoney() != 0){
            CommissionRuleRoot commissionRuleRoot = commissionRootRuleService.getCommissionRuleCK(orderCreditCK.getCityCode(),orderCreditCK.getProductCode(),orderCreditCK.getFirstMoney(),orderCreditCK.getChannelType(),orderCreditCK.getFirstDate());
            if(commissionRuleRoot == null){
                //查询规则
                CommissionMonthRule commissionMonthRule = commissionRootRuleService.getCommissionMonthRule(orderCreditCK.getCityCode(),orderCreditCK.getProductCode(),orderCreditCK.getFirstMoney(),orderCreditCK.getChannelType(),orderCreditCK.getFirstDate());
                setCommissionMonth(orderCreditCK, commissionMonthRule);
            }else{
                setCommission(orderCreditCK, commissionRuleRoot);
            }

        }
    }

    private void setCommissionMonth(OrderCreditCK orderCreditCK, CommissionMonthRule commissionMonthRule) {
        if(commissionMonthRule != null){
            //查询 已发放次数
            int count = orderCreditMonthService.getComputTimes(orderCreditCK.getId());
            int nextCount = count+1;
            if(count < commissionMonthRule.getCountMonth()){
               //查询本次发放金额
                CommissionMonthRuleLink commissionRuleMonthLink = commissionRootRuleService.getNextCommissionRuleMonthLink(commissionMonthRule.getId(),nextCount);
                orderCreditCK.setCommissionFirstMoneyUp(commissionMonthRule.getFirstMoneyUp());
                orderCreditCK.setCommissionFirstMoneyDown(commissionMonthRule.getFirstMoneyDown());
                orderCreditCK.setCommissionMoney(commissionRuleMonthLink.getCommissionMoney());
                orderCreditCK.setRuleCommissionMoney(commissionRuleMonthLink.getCommissionMoney().intValue());
                orderCreditCK.setBeginDate(commissionMonthRule.getBeginDate());
                orderCreditCK.setEndDate(commissionMonthRule.getEndDate());
                orderCreditCK.setIsMonth(CommonConstant.IS_MONTH);
                orderCreditCK.setOverState(CommonConstant.FLOW_OVER);
                orderCreditCK.setRuleId(commissionMonthRule.getId());

                // 存入按月发放记录表
                OrderCreditMonth orderCreditMonth = new OrderCreditMonth();
                BeanUtils.copyProperties(orderCreditCK,orderCreditMonth,"id");
                orderCreditMonth.setId(IceRandomUtils.longUUID());
                orderCreditMonth.setRemark("按月发放第"+nextCount+"次");
                orderCreditMonth.setOverState(CommonConstant.IS_NOT_PUTOUT);
                orderCreditMonth.setCountMonth(commissionMonthRule.getCountMonth());
                orderCreditMonth.setOverCount(nextCount);
                orderCreditMonth.setOrderCreditId(orderCreditCK.getId());
                orderCreditMonth.setRuleId(commissionMonthRule.getId());
                orderCreditMonth.setType(CommonConstant.NUMBER_TYPE_CK);
                orderCreditMonth.setRuleCommissionMoney(commissionRuleMonthLink.getCommissionMoney());
                orderCreditMonthService.saveOrderCreditMonth(orderCreditMonth);
                if(nextCount == commissionMonthRule.getCountMonth()){
                    orderCreditCK.setMonthOverState(CommonConstant.MONTH_FLOW_OVER);
                }else{
                    orderCreditCK.setMonthOverState(CommonConstant.MONTH_FLOW_NOT_OVER);
                }
            }

        }else{
            orderCreditCK.setCommissionMoney(null);
            log.info(orderCreditCK.getOrderCode()+"没有查询到规则");
        }
    }
    private void setCommission(OrderCreditCK orderCreditCK, CommissionRuleRoot commissionRuleRoot) {
        if(commissionRuleRoot != null){
            orderCreditCK.setCommissionFirstMoneyUp(commissionRuleRoot.getFirstMoneyUp());
            orderCreditCK.setCommissionFirstMoneyDown(commissionRuleRoot.getFirstMoneyDown());
            orderCreditCK.setRuleCommissionMoney(commissionRuleRoot.getCommissionMoney());
            orderCreditCK.setCommissionMoney(Double.valueOf(commissionRuleRoot.getCommissionMoney()));
            orderCreditCK.setBeginDate(commissionRuleRoot.getBeginDate());
            orderCreditCK.setEndDate(commissionRuleRoot.getEndDate());
            orderCreditCK.setIsMonth(CommonConstant.IS_NOT_MONTH);
        }else{
            orderCreditCK.setCommissionMoney(null);
            log.info(orderCreditCK.getOrderCode()+"没有查询到规则");
        }
    }

    @Override
    public void computCommissionKD(OrderCreditKd orderCreditKd) {
        if(orderCreditKd != null && orderCreditKd.getFirstMoney() != 0){
            CommissionRuleRoot commissionRuleRoot;
            if(orderCreditKd.getProductType() == CommonConstant.PRODUCT_TYPE_SINGLE){
                commissionRuleRoot = commissionRootRuleService.getCommissionRuleCK(orderCreditKd.getCityCode(),orderCreditKd.getProductCode(),orderCreditKd.getFirstMoney(),orderCreditKd.getChannelType(),orderCreditKd.getFirstDate());
            }else{
                commissionRuleRoot = commissionRootRuleService.getCommissionRuleKD(orderCreditKd.getCityCode(),orderCreditKd.getProductCode(),orderCreditKd.getFirstMoney(),orderCreditKd.getChannelType(),orderCreditKd.getFirstDate());
            }
            if(commissionRuleRoot == null){
                //查询规则
                CommissionMonthRule commissionMonthRule = commissionRootRuleService.getCommissionMonthRule(orderCreditKd.getCityCode(),orderCreditKd.getProductCode(),orderCreditKd.getFirstMoney(),orderCreditKd.getChannelType(),orderCreditKd.getFirstDate());
                setCommissionMonthKd(orderCreditKd, commissionMonthRule);
            }else{
                setCommssion(orderCreditKd,commissionRuleRoot);
            }

        }
    }

    private void setCommissionMonthKd(OrderCreditKd orderCreditkd, CommissionMonthRule commissionMonthRule) {
        if(commissionMonthRule != null){
            //查询 已发放次数
            int count = orderCreditMonthService.getComputTimes(orderCreditkd.getId());
            int nextCount = count+1;
            if(count < commissionMonthRule.getCountMonth()){
                //查询本次发放金额
                CommissionMonthRuleLink commissionRuleMonthLink = commissionRootRuleService.getNextCommissionRuleMonthLink(commissionMonthRule.getId(),nextCount);
                orderCreditkd.setCommissionFirstMoneyUp(commissionMonthRule.getFirstMoneyUp());
                orderCreditkd.setCommissionFirstMoneyDown(commissionMonthRule.getFirstMoneyDown());

                orderCreditkd.setCommissionMoney(commissionRuleMonthLink.getCommissionMoney());
                orderCreditkd.setRuleCommissionMoney(commissionRuleMonthLink.getCommissionMoney().intValue());
                orderCreditkd.setBeginDate(commissionMonthRule.getBeginDate());
                orderCreditkd.setEndDate(commissionMonthRule.getEndDate());
                orderCreditkd.setIsMonth(CommonConstant.IS_MONTH);
                orderCreditkd.setOverState(CommonConstant.FLOW_OVER);
                orderCreditkd.setRuleId(commissionMonthRule.getId());
                if(nextCount == commissionMonthRule.getCountMonth()){
                    orderCreditkd.setMonthOverState(CommonConstant.MONTH_FLOW_OVER);
                }else{
                    orderCreditkd.setMonthOverState(CommonConstant.MONTH_FLOW_NOT_OVER);
                }
                //存入按月发放记录表
                OrderCreditMonth orderCreditMonth = new OrderCreditMonth();
                BeanUtils.copyProperties(orderCreditkd,orderCreditMonth,"id");
                orderCreditMonth.setId(IceRandomUtils.longUUID());
                orderCreditMonth.setRemark("按月发放第"+nextCount+"次");
                orderCreditMonth.setOverState(CommonConstant.IS_NOT_PUTOUT);
                orderCreditMonth.setCountMonth(commissionMonthRule.getCountMonth());
                orderCreditMonth.setOverCount(nextCount);
                orderCreditMonth.setOrderCreditId(orderCreditkd.getId());
                orderCreditMonth.setRuleId(commissionMonthRule.getId());
                orderCreditMonth.setType(CommonConstant.NUMBER_TYPE_CK);
                orderCreditMonth.setRuleCommissionMoney(commissionRuleMonthLink.getCommissionMoney());
                orderCreditMonthService.saveOrderCreditMonth(orderCreditMonth);
            }

        }else{
            orderCreditkd.setCommissionMoney(null);
            log.info(orderCreditkd.getOrderCode()+"没有查询到规则");
        }
    }

    @Override
    public void computCommissionCKC(OrderCreditCK orderCreditCK) {
        if(orderCreditCK != null && orderCreditCK.getFirstMoney() != 0){
            CommissionRuleRoot commissionRuleRoot = commissionRootRuleService.getCommissionRuleCKC(orderCreditCK.getCityCode(),orderCreditCK.getProductCode(),orderCreditCK.getFirstMoney(),orderCreditCK.getFirstDate());
            setCommission(orderCreditCK, commissionRuleRoot);
        }
    }

    @Override
    public void computCommissionKDC(OrderCreditKd orderCreditKd) {
        if(orderCreditKd != null && orderCreditKd.getFirstMoney() != 0){
            CommissionRuleRoot commissionRuleRoot;
            if(orderCreditKd.getProductType() == CommonConstant.PRODUCT_TYPE_SINGLE){
                commissionRuleRoot = commissionRootRuleService.getCommissionRuleCKC(orderCreditKd.getCityCode(),orderCreditKd.getProductCode(),orderCreditKd.getFirstMoney(),orderCreditKd.getFirstDate());
            }else{
                commissionRuleRoot = commissionRootRuleService.getCommissionRuleKDC(orderCreditKd.getCityCode(),orderCreditKd.getProductCode(),orderCreditKd.getFirstMoney(),orderCreditKd.getFirstDate());
            }
            setCommssion(orderCreditKd,commissionRuleRoot);
        }
    }



    @Override
    @Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
    public void computeCommissionMonth(OrderCreditMonth orderCreditMonth) {
        if(orderCreditMonth != null){
            //查询规则
            CommissionMonthRule commissionMonthRule = commissionRootRuleService.getCommissionMonthRuleById(orderCreditMonth.getRuleId());
            setCommissionMonth(orderCreditMonth, commissionMonthRule);
        }

    }

    /**
     * 此处orderCreditMonth 封装的是Ordercreditck 或者 ordercreditkd 数据，所以id是那两张表id 方便开发，切记不要混淆
     * orderCreditMonthNew 对应新表数据
     */
    private void setCommissionMonth(OrderCreditMonth orderCreditMonth, CommissionMonthRule commissionMonthRule) {
        //查询 已发放次数
        int count = orderCreditMonthService.getComputTimes(orderCreditMonth.getId());
        int nextCount = count+1;
        if(commissionMonthRule != null){
            // 不在时间段内结束
            if(IceDateOperationUtils.isBefore(orderCreditMonth.getFirstDate(),commissionMonthRule.getEndDate()) &&
                    IceDateOperationUtils.isAfter(orderCreditMonth.getFirstDate(),commissionMonthRule.getBeginDate())  ){
                if(count < commissionMonthRule.getCountMonth()){
                    switch (edtApiService.validateOnlineState(orderCreditMonth.getServiceCode(),orderCreditMonth.getOrderCode(),orderCreditMonth.getOrderDate(),null,null)){
                        case CommonConstant.KFK_VALIDATE_RESULT_ZC:
                            //查询本次发放金额
                            CommissionMonthRuleLink commissionMonthRuleLink = commissionRootRuleService.getNextCommissionRuleMonthLink(commissionMonthRule.getId(),nextCount);
                            //存入按月发放记录表
                            OrderCreditMonth orderCreditMonthNew = new OrderCreditMonth();
                            BeanUtils.copyProperties(orderCreditMonth,orderCreditMonthNew,"id","commissionMoney");
                            saveNeedPutOutOrderCreditMonth(orderCreditMonth.getId(),orderCreditMonthNew,nextCount,commissionMonthRule,commissionMonthRuleLink);
                            break;
                        case CommonConstant.KFK_VALIDATE_RESULT_XH:
                            overFlowOrderCreditAndAppendRemark(orderCreditMonth.getId(),orderCreditMonth.getType(),
                                    "发放第"+nextCount+"次"+"接口验证已销户 发放流程结束");
                            break;
                        case CommonConstant.KFK_VALIDATE_RESULT_QF:case CommonConstant.KFK_VALIDATE_RESULT_WZ:
                            //存入按月发放记录表
                            OrderCreditMonth orderCreditMonthNewError = new OrderCreditMonth();
                            BeanUtils.copyProperties(orderCreditMonth,orderCreditMonthNewError,"id","commissionMoney");
                            saveNeedNotPutOutOrderCreditMonth(orderCreditMonth.getId(),orderCreditMonthNewError,nextCount,commissionMonthRule,"发放第"+nextCount+"次"+"验证欠费");
                            break;
                    }
                }else{
                    overFlowOrderCreditAndAppendRemark(orderCreditMonth.getId(),orderCreditMonth.getType(),
                            "发放第"+nextCount+"次"+"规则改变次数变少");
                }
            }else{
                overFlowOrderCreditAndAppendRemark(orderCreditMonth.getId(),orderCreditMonth.getType(),
                        "发放第"+nextCount+"次"+"有效时间段改变 发放流程结束");
            }

        }else{
            overFlowOrderCreditAndAppendRemark(orderCreditMonth.getId(),orderCreditMonth.getType(),
                    "发放第"+nextCount+"次"+"没有查询到规则 发放流程结束");
            log.info(orderCreditMonth.getOrderCode()+"没有查询到规则");
        }
    }

    private void saveNeedPutOutOrderCreditMonth(String orderCreditId, OrderCreditMonth orderCreditMonth, int putoutTimes, CommissionMonthRule commissionMonthRule, CommissionMonthRuleLink commissionMonthRuleLink){
        orderCreditMonth.setId(IceRandomUtils.longUUID());
        orderCreditMonth.setRemark("按月发放第"+putoutTimes+"次");
        orderCreditMonth.setOverState(CommonConstant.IS_NOT_PUTOUT);
        orderCreditMonth.setCountMonth(commissionMonthRule.getCountMonth());
        orderCreditMonth.setOverCount(putoutTimes);
        orderCreditMonth.setCommissionMoney(commissionMonthRuleLink.getCommissionMoney());
        orderCreditMonth.setOrderCreditId(orderCreditId);
        orderCreditMonth.setRuleId(commissionMonthRule.getId());
        orderCreditMonth.setRuleCommissionMoney(commissionMonthRuleLink.getCommissionMoney());
        orderCreditMonthService.saveOrderCreditMonth(orderCreditMonth);
        if(putoutTimes == commissionMonthRule.getCountMonth()){
            overFlowOrderCreditAndAppendRemark(orderCreditId,orderCreditMonth.getType(),"按月发放流程发满结束");
        }
        orderCreditService.addCommissionMoney(orderCreditMonth.getOrderCode(),commissionMonthRuleLink.getCommissionMoney());
    }

    private void saveNeedNotPutOutOrderCreditMonth(String orderCreditId, OrderCreditMonth orderCreditMonth, int putoutTimes, CommissionMonthRule commissionMonthRule, String remark){
        orderCreditMonth.setId(IceRandomUtils.longUUID());
        orderCreditMonth.setRemark(remark);
        orderCreditMonth.setOverState(CommonConstant.IS_PUTOUT);
        orderCreditMonth.setCountMonth(commissionMonthRule.getCountMonth());
        orderCreditMonth.setOverCount(putoutTimes);
        orderCreditMonth.setCommissionMoney(-1d);
        orderCreditMonth.setOrderCreditId(orderCreditId);
        orderCreditMonth.setRuleId(commissionMonthRule.getId());
        orderCreditMonthService.saveOrderCreditMonth(orderCreditMonth);
        if(putoutTimes == commissionMonthRule.getCountMonth()){
            overFlowOrderCreditAndAppendRemark(orderCreditId,orderCreditMonth.getType(),remark);
        }else{
            appendRemark(orderCreditId,orderCreditMonth.getType(),
                    remark);
        }

    }
    private void appendRemark(String orderId, int orderType, String remark){
        if(CommonConstant.NUMBER_TYPE_CK == orderType){
            orderCreditCKService.appendRemark(orderId,remark);
        }else if(CommonConstant.NUMBER_TYPE_KD == orderType){
            orderCreditKdService.appendRemark(orderId,remark);
        }
    }
    private void overFlowOrderCredit(String orderId, int orderType){
        if(CommonConstant.NUMBER_TYPE_CK == orderType){
            orderCreditCKService.overFlowMonthCommission(orderId);
        }else if(CommonConstant.NUMBER_TYPE_KD == orderType){
            orderCreditKdService.overFlowMonthCommission(orderId);
        }
    }
    private void overFlowOrderCreditAndAppendRemark(String orderId, int orderType, String remark){
        if(CommonConstant.NUMBER_TYPE_CK == orderType){
            orderCreditCKService.overFlowMonthCommission(orderId);
            orderCreditCKService.appendRemark(orderId,remark);
        }else if(CommonConstant.NUMBER_TYPE_KD == orderType){
            orderCreditKdService.overFlowMonthCommission(orderId);
            orderCreditKdService.appendRemark(orderId,remark);
        }
    }

    private void setCommssion(OrderCreditKd orderCreditKd,CommissionRuleRoot commissionRuleRoot){
        if(commissionRuleRoot != null){
            orderCreditKd.setCommissionFirstMoneyUp(commissionRuleRoot.getFirstMoneyUp());
            orderCreditKd.setCommissionFirstMoneyDown(commissionRuleRoot.getFirstMoneyDown());
            orderCreditKd.setRuleCommissionMoney(commissionRuleRoot.getCommissionMoney());
            orderCreditKd.setCommissionMoney(Double.valueOf(commissionRuleRoot.getCommissionMoney()));
            orderCreditKd.setBeginDate(commissionRuleRoot.getBeginDate());
            orderCreditKd.setEndDate(commissionRuleRoot.getEndDate());
            orderCreditKd.setIsMonth(CommonConstant.IS_NOT_MONTH);
        }else{
            orderCreditKd.setCommissionMoney(null);
            log.info(orderCreditKd.getOrderCode()+"没有查询到规则");
        }
    }
}
